package com.boctech.yxt.authcenter.filter;

import com.boctech.yxt.authcenter.entity.JwtProperties;
import com.boctech.yxt.authcenter.service.MyUserDetailService;
import com.boctech.yxt.authcenter.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private JwtProperties jwtProperties;

    private JwtTokenUtils jwtTokenUtils;

    private MyUserDetailService userDetailService;

    public JwtAuthenticationTokenFilter(JwtProperties jwtProperties, JwtTokenUtils jwtTokenUtils, MyUserDetailService userDetailService){
        this.jwtTokenUtils = jwtTokenUtils;
        this.jwtProperties = jwtProperties;
        this.userDetailService = userDetailService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader(jwtProperties.getHeader());
        // 当token不为空的时候创建验证对象，表示已经验证过，不再需要验证
        if (token != null){
            String nameFromToken = jwtTokenUtils.getUserNameFromToken(token);
            // 只有用户名不为空并且之前没有验证过才需要进行验证
            if (nameFromToken != null && SecurityContextHolder.getContext().getAuthentication() == null){
                UserDetails userDetails = userDetailService.loadUserByUsername(nameFromToken);
                // 如果token没有过期
                if (! jwtTokenUtils.isTokenExpired(token)){
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}
